from django import http
from django.http import HttpResponsePermanentRedirect
from django.urls import reverse
from django.views import View
from django.shortcuts import render, redirect
from django.contrib.auth import logout

from operation.models import UserCourse
from users.forms import RegisterForm
from users.forms import LoginForm
import re
from users.models import UserProfile
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from users.forms import ForgetForm
from boxuegu.settings import EMAIL_VERIFY_URL, SECRET_KEY
from celery_tasks.email.tasks import send_verify_email
from courses.models import Course, BannerCourse
from organization.models import CourseOrg
from users.models import Banner


class IndexView(View):
    """1. 首页展示"""

    def get(self, request):
        # all_banners = Banner.objects.all()
        # courses = Course.objects.all()
        # banner_courses = BannerCourse.objects.all()
        # course_orgs = CourseOrg.objects.all()

        return render(request, 'index.html')
        # , {
        #     'all_banners': all_banners,  # 获取轮播图表(Banner)所有轮播图数据
        #     'courses': courses,  # 获取课程信息表(Course)中的课程信息数据
        #     'banner_courses': banner_courses,  # 获取课程信息表中(Course)的课程信息数据 和上面数据一样
        #     'course_orgs': course_orgs,  # 获取课程学校表(CourseOrg)中的数据
        # })


class RegisterView(View):
    """2. 用户注册"""

    # 获取注册页面
    def get(self, request):
        register_form = RegisterForm(request.GET)
        return render(request, 'register.html', {'register_form': register_form})

    # 点击注册保存用户数据
    def post(self, request):
        email = request.POST.get('email')
        password = request.POST.get('password')
        captcha = request.POST.get('captcha')  # 验证码
        # 验证数据是否齐全
        if all([email, password, captcha]):
            # 验证格式
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return http.HttpResponseBadRequest({'邮箱格式错误'})
            if not re.match(r'^[0-9A-Za-z]{5,20}$', password):
                return http.HttpResponseBadRequest('请输入8-20位的密码')
            # 验证成功保存用户信息
            request.user.email = email
            request.user.password = password
            request.user.save()
            return render(request, 'index.html')
        else:
            register_form = RegisterForm(request.POST)
            return render(request, 'register.html', {'register_form': register_form})


class LoginView(View):
    """3. 用户登录"""

    # 获取登录页面
    def get(self, request):
        return render(request, 'login.html')

    # 完成登录请求
    def post(self, request):
        email = request.get('email')
        password = request.get('password')
        # 验证数据是否齐全
        if all([email, password]):
            return HttpResponsePermanentRedirect(reverse('index'))
        else:
            login_form = LoginForm(request.GET)
            return render(request, 'login.html', {'form_errors': login_form.errors})


class LogoutView(View):
    """4. 用户退出"""

    def get(self, request):
        logout(request)
        # 跳转页面
        response = redirect(reverse('contents:index'))
        return response


def verify_email_url(user_id):
    """获取用户id的视图函数，从而发送邮件验证<---服务于忘记密码"""
    # 1.创建实例
    s = Serializer(secret_key=SECRET_KEY, expires_in=3600)
    # 2.组织数据
    data = {'user_id': str(user_id)}
    # 3.加密数据
    active_code = s.dumps(data)
    # 4.返回数据
    return EMAIL_VERIFY_URL + active_code.decode()


def check_email_url(active_code):
    """"通过用户加密的active_code值检查邮箱路由<---服务于忘记密码"""
    s = Serializer(SECRET_KEY, expires_in=3600)
    # 解密
    data = s.loads(active_code)
    # 查询
    username = data.get('user_id')
    try:
        user = UserProfile.objects.get(username=username)
        # print(user)
    except Exception as e:
        print(e)
    else:
        return user


class ForgetPwdView(View):
    """5. 忘记密码"""
    '''
1. 获取忘记密码界面
需求: 当用户在登录页面点击忘记密码时获取忘记密码页面
后端: 请求方式和路由 GET  forget/
    1. 接收请求
    2. 返回忘记密码界面(forget_form)
2. 发送邮件
需求: 当用户输入邮箱和验证码点击提交时，验证表单数据，然后发送邮件到用户邮箱
后端: 请求方式和路由 POST forget/
    步骤:
        1.接收用户输入的注册邮箱和图片验证码
        2.验证
            2.1 验证数据是否齐全
            2.2 验证邮箱格式
            2.3 验证邮箱是否已注册
            2.4 验证图片验证码--未解决
        3.验证失败返回‘forget_form’(其实就是href=#)
        4.验证成功给用户邮箱发送邮件
        5.返回成功界面'send_success.html'
'''

    # 获取忘记密码页面
    def get(self, request):
        forget_form = ForgetForm()
        return render(request, 'forgetpwd.html', {'forget_form': forget_form})

    # 发送邮件
    def post(self, request):
        data = request.POST
        forget_form = ForgetForm(data)
        # 验证
        ret = forget_form.is_valid()
        if ret:
            email = data.get('email')
            try:
                email_id = UserProfile.objects.get(email=email)
            except Exception as e:
                # print(e)
                return render(request, 'forgetpwd.html', {'forget_form': forget_form, 'error': '邮箱未注册'})
                # return render(request, 'forgetpwd.html', {'forget_form': forget_form})
            else:
                # 发送邮件
                subject = '博学谷邮箱修改密码验证'
                message = ''
                from_email = '博学谷<wang_han_yong@163.com>'
                recipient_list = [email]
                email_url = verify_email_url(email_id)  # 激活的url: verify_url = 'http://?token=xxx'
                html_message = '<p><a href="%s">%s<a></p>请点击下面的链接重置你的密码' % (email_url, email_url)
                send_verify_email.delay(subject=subject,
                                        message=message,
                                        from_email=from_email,
                                        recipient_list=recipient_list,
                                        html_message=html_message
                                        )
                return render(request, 'send_success.html')
        # 5. 返回响应
        return render(request, 'forgetpwd.html', {'forget_form': forget_form})


class ResetView(View):
    """6. 修改密码"""
    '''
    需求: 用户点击邮箱内的链接进入到修改密码界面，输入新密码，
    '''

    def get(self, request, active_code):
        try:
            user = check_email_url(active_code)  # 用户加密的active_code值
        except Exception as e:
            print(e)
            return render(request, 'active_fail.html')
        else:
            if user is not None:
                forget_form = ForgetForm()
                # 添加验证
                ret = forget_form.is_valid()
                if ret:
                    return render(request, 'password_reset.html', {'email': user.email})
                else:
                    render(request, 'active_fail.html')
            else:
                render(request, 'active_fail.html')


class UploadImageView(View):
    """7. 用户中心------个人资料"""

    def get(self, request):
        """获取当前登录用户信息"""
        # 在模板中可以通过request对象获取用户信息
        return render(request, 'usercenter-info.html')

        # def post(self, request, msg):
        #     """修改头像"""
        #     # 1. 接收用户
        #     msg = request.POST.get('msg')


class UserInfoView(View):
    """8. 修改用户信息"""
    def get(self, request):
        return render(request, 'usercenter-info.html')

    def post(self, request):
        # if :
        #     # 修改成功
        #     return http.JsonResponse({ "status":"success"})
        # else:
        #     # 修改失败
        #     return http.JsonResponse({ "status":"error"})
        pass


class MyCourseView(View):
    """用户课程"""
    """
    需求:用户点击我的课程，获取用户课程表(UserCourse)的数据返回
    """
    def get(self, request):
        user = request.user
        user_courses = UserCourse.objects.filter(user=user)
        return render(request, 'usercenter-mycourse.html', {'user_courses': user_courses})


class MyMessageView(View):
    pass


class MyFavOrgView(View):
    pass